<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
</head>

<body>
  <script>
    const data = {
      name: '你好',
      age: 18,
      test: {
        name2: 'hi',
      },
      test2: {
        name2: 'hi',
      },
      arr: [1, 2, 3],
    };
    //处理数组问题
    const oldArr = Array.prototype;
    const newArr = Object.create(oldArr);
    ['push', 'pop', 'shift', 'unshift', 'splice'].forEach((methodsName) => {
      console.log(this, 111)
      newArr[methodsName] = function () {
        console.log('数组更新视图', this, 22);
        oldArr[methodsName].call(this, ...arguments);
      };
    });
    observe(data);
    function observe(target) {
      if (!target || typeof target !== 'object') {
        return target;
      }
      console.log(target, 222);
      //处理数组
      if (Array.isArray(target)) {
        console.log(newArr);
        target.__proto__ = newArr;
        console.log(target);
      }
      Object.keys(target).forEach((key) => {
        defineReactive(target, key, target[key]);
      });
      function defineReactive(target, key, value) {
        observe(value); //解决对象里面还有对象问题
        Object.defineProperty(target, key, {
          get() {
            return value;
          },
          set(newValue) {
            observe(value); //改变指向
            if (newValue !== value) {
              value = newValue;
              console.log('视图要更新');
            }
          },
        });
      }
    }
    //只有一层数据
    //   data.name = '你好呀';

    //两层以上数据
    //   data.test.name2 = '你好呀';

    //改变对象指向
    //   data.age = { name3: hi };
    //   data.test2 = { name3: 'hi' }; //试图还是会更新
    //   data.test2.name3 = '你好呀'; //此时不会更新

    //数组改变
    //data.arr[0] = 0; //视图会更新
    data.arr.push(4); //视图不更新
  </script>
</body>

</html>